﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.Script.Serialization;
using System.Web.Mvc;
using ESN.Models;
using ESN.Languages;
using ESN.Helpers;
using System.Data.Entity;
using System.IO;
using System.Configuration;

namespace ESN.Controllers
{
    [Authorize]
    public class HomeController : Controller
    {
        private ESNCoreDbContext core = new ESNCoreDbContext();
        [AllowAnonymous]
        public ActionResult Index()
        {
            ViewBag.Members = core.Profiles.Where(m => !m.isPrivate).OrderBy(m => m.UserId).Take(18);
            ViewBag.Groups = core.Groups.Where(g => g.GPermission > 0).OrderByDescending(g => g.GId).Take(18);
            ViewBag.Canvas = core.CanvasSessions.Where(c => c.isPublic).OrderByDescending(c => c.ID).Take(18);
            ViewBag.Folders = core.Folders.Where(f => f.isPublic).OrderByDescending(f => f.FId).Take(18);
            ViewBag.Title = LangString.Load("welcome", "Home");
            ViewBag.NewMem = LangString.Load("new_mem", "Home");
            ViewBag.NewGroup = LangString.Load("new_group", "Home");
            ViewBag.NewCanvas = LangString.Load("new_canvas", "Home");
            ViewBag.NewFolder = LangString.Load("new_folders", "Home");
            return View();
        }
        [AllowAnonymous]
        public ActionResult UserHome(string name)
        {
            var user = Membership.GetUser(name);
            if (user == null)
            {
                ViewBag.Detail = LangString.Load("user_not_found", "Error");
                return View("Error");
            }
            CustomProfile p = core.Profiles.Find((Guid)user.ProviderUserKey);
            ViewBag.Friends = p.Friends.Take(20);

            ViewBag.PostWall = PermissionHelper.postWall(p.UserId);
            ViewBag.ReadWall = PermissionHelper.readWall(p.UserId);
            if (ViewBag.ReadWall)
            {
                var wall = core.UserWalls.Include("Writer").Include("Attachments").Where(w => w.UserId == p.UserId && w.ParentWId == null).OrderByDescending(w => w.WId).Take(20);
                ViewBag.First20Walls = wall;
            }
            if (!PermissionHelper.isFriend(p.UserId) && !PermissionHelper.IsOwner(p.UserId))
            {
                ViewBag.ShowFriendRequest = true;
            }
            else
            {
                ViewBag.ShowFriendRequest = false;
            }
            ViewBag.Home = LangString.Load("user_home", "Home");
            ViewBag.ShouldLoggin = LangString.Load("user_should_loggin", "Home");
            ViewBag.PublicWall = LangString.Load("public_wall", "Home");
            ViewBag.AttFile = LangString.Load("att_file", "Home");
            ViewBag.Cancel = LangString.Load("cancel", "Home");
            ViewBag.Save = LangString.Load("save", "Home");
            return View(p);
        }

        public ActionResult UserSetting(string name)
        {
            if (PermissionHelper.IsOwner(name))
            {                
                var profile = core.Profiles.Find((Guid)Membership.GetUser(name).ProviderUserKey);
                ViewBag.Title = LangString.Load("user_setting", "Home");
                ViewBag.Des = LangString.Load("user_setting_des", "Home");
                ViewBag.isPrivate = LangString.Load("private", "Profile");
                ViewBag.DisplayName = LangString.Load("displayname", "Profile");
                ViewBag.FirstName = LangString.Load("firstname", "Profile");
                ViewBag.Lastname = LangString.Load("lastname", "Profile");
                ViewBag.Location = LangString.Load("location", "Profile");
                ViewBag.Avatar = LangString.Load("Avatar", "Profile");
                ViewBag.ChangeAvatar = LangString.Load("avt_change", "Home");
                ViewBag.Gender = LangString.Load("gender", "Profile");
                ViewBag.Man = LangString.Load("man", "Profile");
                ViewBag.Woman = LangString.Load("woman", "Profile");
                ViewBag.WallPermission = LangString.Load("wallpermission", "Profile");
                ViewBag.Read = LangString.Load("read", "Profile");
                ViewBag.Post = LangString.Load("write", "Profile");
                ViewBag.Friend = LangString.Load("friend", "Home");
                ViewBag.User = LangString.Load("user", "Home");
                ViewBag.Guest = LangString.Load("guest", "Home");
                ViewBag.Save = LangString.Load("save", "Home");
                return View(profile);
            }
            return RedirectToAction("Index");
        }
        [HttpPost]
        public ActionResult UpdateProfile(CustomProfile p)
        {
            if (ModelState.IsValid)
            {
                var profile = core.Profiles.Find(p.UserId);
                profile.isPrivate = p.isPrivate;
                profile.DisplayName = p.DisplayName;
                profile.FirstName = p.FirstName;
                profile.LastName = p.LastName;
                profile.Location = p.Location;
                profile.Avatar = p.Avatar;
                profile.Gender = p.Gender;
                profile.Additional = p.Additional;
                profile.WallPermission = p.WallPermission;
                core.SaveChanges();
                return Redirect("/" + profile.UserName + "/Home");
            }
            return Redirect("/" + p.UserName + "/Settings");
        }

        public ActionResult UpdateAvatar(string name)
        {
            if (!PermissionHelper.IsOwner(name))
                return RedirectToAction("Index", "Home");

            var profile = core.Profiles.Find((Guid)Membership.GetUser(name).ProviderUserKey);
            ViewBag.Title = LangString.Load("avt_change", "Home");
            return View(profile);
        }
        [HttpPost]
        public ActionResult UpdateAvatar(HttpPostedFileBase file)
        {
            if (Request.Form["UserId"] == null)
            {
                ViewBag.Detail = LangString.Load("error", "Error");
                return View("Error");
            }


            Guid userId = new Guid(Request.Form["UserId"]);
            if (!PermissionHelper.IsOwner(userId))
            {
                ViewBag.Detail = LangString.Load("permission_change_avt", "Error");
                return View("Error");
            }

            if (file.ContentType != "image/pjpeg" &&
                file.ContentType != "image/jpeg" &&
                file.ContentType != "image/png" &&
                file.ContentType != "image/gif")
            {
                ViewBag.Detail = LangString.Load("invalid_img_type", "Error");
                return View("Error");
            }

            var realFileName = Path.GetFileName(file.FileName);

            var binary = new byte[file.ContentLength];
            file.InputStream.Read(binary, 0, file.ContentLength);

            var response = "";

            string path = ConfigurationManager.AppSettings["Avatars"];

            try
            {
                response = RemoteHelper.Put("https://apis.live.net/v5.0/" + path + "/files/Avatar-" + Request.Form["UserId"] + realFileName + "?access_token=" + core.AppToken.Find(1).access_token, binary);
            }
            catch
            {
                ViewBag.Detail = LangString.Load("permission_change_avt", "Error");
                return View("Error");
            }

            var parser = new JavaScriptSerializer();
            LiveFile liveResponse = parser.Deserialize<LiveFile>(response);

            var user = core.Profiles.Find(userId);
            if (user == null)
            {
                ViewBag.Detail = LangString.Load("error", "Error");
                return View("Error");
            }

            user.Avatar = RemoteHelper.GetRedirect(liveResponse.source);
            core.SaveChanges();
            ViewBag.Updated = true;
            //return LangString.Load("avt_updated", "Home");
            return View(user);
        }

        [HttpPost]
        public string UploadAttachment(HttpPostedFileBase file)
        {
            if (Request.Form["UserId"] == null)
                return "{\"error\":\"" + LangString.Load("error", "Error") + "\"}";

            Guid userId = new Guid(Request.Form["UserId"]);
            if (!PermissionHelper.IsOwner(userId))
                return "{\"error\":\""+ LangString.Load("permission_cant", "Error") +"\"}";

            bool isImage = false;
            if (file.ContentType == "image/pjpeg" ||
                file.ContentType == "image/jpeg" ||
                file.ContentType == "image/png" ||
                file.ContentType == "image/gif")
                isImage = true;

            var realFileName = Path.GetFileName(file.FileName);

            var binary = new byte[file.ContentLength];
            file.InputStream.Read(binary, 0, file.ContentLength);

            var response = "";

            string path = "";
            if (isImage)
                path = ConfigurationManager.AppSettings["Pictures"];
            else
                path = ConfigurationManager.AppSettings["Documents"];

            try
            {

                response = RemoteHelper.Put("https://apis.live.net/v5.0/" + path + "/files/Wall-BY-" + Request.Form["UserId"] + "-AT-" + DateTime.Now.ToString("yyyyMMddHHmmssffff") + "-NAME-" + realFileName + "?access_token=" + core.AppToken.Find(1).access_token, binary);
            }
            catch(Exception e)
            {
                return "{\"error\":\"" + LangString.Load("upload_failed", "Error") + e.Message + ".\"}";
            }
            var parser = new JavaScriptSerializer();
            LiveFile liveResponse = parser.Deserialize<LiveFile>(response);

            var user = core.Profiles.Find(userId);
            if (user == null)
                return "{\"error\":\"" + LangString.Load("error", "Error") + "\"}";

            Attachment att = new Attachment();
            att.isImage = isImage;
            att.UserId = userId;
            att.AName = realFileName;
            att.AKey = liveResponse.id;

            if (string.IsNullOrEmpty(Request.Form["isPublic"]))
                att.isPublic = false;
            else
                att.isPublic = true;

            if (isImage)
                att.ASource = RemoteHelper.GetRedirect(liveResponse.source);
            else
                att.ASource = liveResponse.source;

            core.Attachments.Add(att);
            core.SaveChanges();
            return "{\"AId\": " + att.AId + ", \"ASource\" : \"" + att.ASource + "\", \"isImage\": " + isImage.ToString().ToLower() + ", \"AName\" : \"" + att.AName + "\"}";
        }
        public ActionResult DownloadAttachment(int id)
        {
            var att = core.Attachments.Find(id);
            Object f = new Object();
            var parser = new JavaScriptSerializer();
            try
            {
                f = parser.Deserialize<Object>(RemoteHelper.Get("https://apis.live.net/v5.0/" + att.AKey + "/?access_token=" + core.AppToken.Find(1).access_token));
            }
            catch
            {
                ViewBag.Error = LangString.Load("error", "Error");
            }
            ViewBag.Mess = LangString.Load("file_download_notice", "Home");
            ViewBag.UserDisplayName = att.Profiles.DisplayName;
            ViewBag.UserName = att.Profiles.UserName;
            ViewBag.FileName = att.AName;
            ViewBag.Url = f;
            ViewBag.DownloadTitle = LangString.Load("download_att", "Home");
            ViewBag.Owner = LangString.Load("owner", "Home");
            return View();
        }
        public ActionResult MyGroups(string name)
        {
            if (PermissionHelper.IsOwner(name))
            {
                var id = (Guid)Membership.GetUser(name).ProviderUserKey;
                ViewBag.UserId = id.ToString();
                ViewBag.JoinGroups = core.Groups.Where(g => g.Members.Select(u=>u.UserId).Contains(id));
                ViewBag.OwnGroups = core.Groups.Where(g => g.OwnerId == id);
                ViewBag.Title = LangString.Load("group", "Home");
                ViewBag.GroupOwn = LangString.Load("group_own", "Home");
                ViewBag.GroupJoin = LangString.Load("group_join", "Home");
                ViewBag.GroupCreate = LangString.Load("group_create", "Home");
                ViewBag.GroupName = LangString.Load("gname", "Group");
                ViewBag.GroupDes = LangString.Load("gdescription", "Group");
                ViewBag.GroupPermission = LangString.Load("gpermission", "Group");
                ViewBag.GroupPermissionInvite = LangString.Load("gpermission_inv", "Group");
                ViewBag.GroupPermissioRequest = LangString.Load("gpermission_re", "Group");
                ViewBag.GroupPermissionFree = LangString.Load("gpermission_free", "Group");
                ViewBag.Read = LangString.Load("read", "Profile");
                ViewBag.Post = LangString.Load("post", "Profile");
                ViewBag.Member = LangString.Load("member", "Home");
                ViewBag.User = LangString.Load("user", "Home");
                ViewBag.Guest = LangString.Load("guest", "Home");
                ViewBag.Save = LangString.Load("save", "Home");
                return View();
            }
            return RedirectToAction("Index");
        }

        [HttpPost]
        public ActionResult MyGroups(Group g)
        {
            Guid id = (Guid)Membership.GetUser().ProviderUserKey;
            g.OwnerId = id;
            core.Groups.Add(g);
            core.SaveChanges();
            ViewBag.UserId = id.ToString();
            ViewBag.Title = LangString.Load("group", "Home");
            ViewBag.GroupOwn = LangString.Load("group_own", "Home");
            ViewBag.GroupJoin = LangString.Load("group_join", "Home");
            ViewBag.GroupCreate = LangString.Load("group_create", "Home");
            ViewBag.GroupName = LangString.Load("gname", "Group");
            ViewBag.GroupDes = LangString.Load("gdescription", "Group");
            ViewBag.GroupPermission = LangString.Load("gpermission", "Group");
            ViewBag.GroupPermissionInvite = LangString.Load("gpermission_inv", "Group");
            ViewBag.GroupPermissioRequest = LangString.Load("gpermission_re", "Group");
            ViewBag.GroupPermissionFree = LangString.Load("gpermission_free", "Group");
            ViewBag.Read = LangString.Load("read", "Profile");
            ViewBag.Post = LangString.Load("post", "Profile");
            ViewBag.Member = LangString.Load("member", "Home");
            ViewBag.User = LangString.Load("user", "Home");
            ViewBag.Guest = LangString.Load("guest", "Home");
            ViewBag.Save = LangString.Load("save", "Home");
            return View();
        }

        public ActionResult MyNotices(string name)
        {
            if (PermissionHelper.IsOwner(name))
            {
                Guid id = (Guid)Membership.GetUser().ProviderUserKey;
                ViewBag.UserName = name;
                //var Notices = core.UserNotices.OrderByDescending(n => n.NId).Where(n => n.NNew && n.Profiles.UserName == name).Take(20);
                var Notices = core.UserNotices.Where(n => n.NNew && n.UserId == id).OrderByDescending(n => n.NId).Take(20);
                var data = Notices.ToList();
                foreach (var nt in Notices)
                {
                    nt.NNew = false;
                }
                core.SaveChanges();
                return View(data);
            }
            ViewBag.Title = LangString.Load("user_notice", "Home");
            return RedirectToAction("Index");
        }

        public ActionResult MyFriendRequests(string name)
        {
            if (PermissionHelper.IsOwner(name))
            {
                Guid id = (Guid)Membership.GetUser().ProviderUserKey;
                ViewBag.ForYou = core.FriendRequests.Include("Profiles").Where(r => r.FriendId == id).Take(20);
                ViewBag.ByYou = core.FriendRequests.Include("Friend").Where(r => r.UserId == id);
                ViewBag.UserName = name;
                return View();
            }
            ViewBag.Title = LangString.Load("user_request", "Home");
            ViewBag.RequestBy = LangString.Load("user_request_by", "Home");
            ViewBag.RequestFor = LangString.Load("user_request_for", "Home");
            return RedirectToAction("Index");
        }

        public ActionResult FriendList(string name)
        {
            var user = core.Profiles.Where(u => u.UserName == name).Single();
            ViewBag.Profile = user;
            var fr = user.Friends.OrderByDescending(f => f.UserId).Take(20);

            if (!user.Friends.Contains(core.Profiles.Find((Guid)Membership.GetUser().ProviderUserKey)) && !PermissionHelper.IsOwner(name))
            {
                ViewBag.ShowFriendRequest = true;
            }
            else
            {
                ViewBag.ShowFriendRequest = false;
            }
            ViewBag.FrList = LangString.Load("fr_list", "Home");
            ViewBag.DisplayName = LangString.Load("displayname", "Profile");
            ViewBag.Location = LangString.Load("location", "Profile");
            ViewBag.Gender = LangString.Load("gender", "Profile");
            ViewBag.Man = LangString.Load("man", "Profile");
            ViewBag.Woman = LangString.Load("woman", "Profile");
            return View(fr);
        }
    }
}
